<!DOCTYPE html>
<html>

<head>
	<meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes">
	<title>图片混淆</title>
</head>

<body>
	<style>
		.main h1 {
			margin-block-start: 0.5em;
			margin-block-end: 0.2em;
		}
		.main input {
			background-color: rgba(0, 0, 0, 0);
			border: none;
			border-bottom-color: rgb(115, 115, 115);
			border-bottom-style: solid;
			border-bottom-width: 2px;
			color: rgb(0, 0, 0);
			outline-style: none;
			height: 24px;
			width: 200px;
			font-family: "Segoe UI", Arial, Helvetica, sans-serif;
			font-size: 16px;
			text-align: center;
			margin-bottom: 1px;
			margin-top: 5px;
		}
		.main #ikey:focus,
		.main #ikey2:focus{
			border: none;
			border-bottom-color: rgb(1, 133, 119);
			border-bottom-style: solid;
			border-bottom-width: 3px;
			margin-bottom: 0px;
		}

		.main button {
			-webkit-transition-duration: 0.2s;
 			transition-duration: 0.2s;
			background: rgb(215,215,215);
			border: none;
			box-shadow: 3px 3px 8px 0px #aaa;
			height: 35px;
			width: 70px;
			font-family: "Segoe UI", Arial, Helvetica, sans-serif;
			font-size: 12px;
		}

		.main button:hover{
			background-color: rgb(190,190,190);
		}

		.main select {
			background: #fff;
			border: 1px solid #aaa;
			height: 1.5rem;
			font-family: "Segoe UI", Arial, Helvetica, sans-serif;
		}

		.main .shuoming{
			color: #444444;
			font-family: 'Segoe UI', Arial, Helvetica, sans-serif;
			font-size: 12px;
		}

		#kimg {
			width: auto;
			height: auto;
			display: none;
			margin: 0 auto;
		}

		.main .square {
			width: 200px;
			height: 200px;
			text-align: center;
			justify-content: center;
			align-items: center;
			background: #fbfbfb;
			border: 2px solid #999;
			color: #666;
			margin: 0 auto;
			font-family: "Segoe UI", Arial, Helvetica, sans-serif;
		}

		#sign {
			display: flex;
		}

		#imgwrap {
			display: none;
			overflow: hidden;
			line-height: 70px;
		}

		#loading {
			display: none;
		}

		/* 遮罩层 */
		#overlay {
			position: fixed;
			left: 0px;
			top: 0px;
			width: 100%;
			height: 100%;
			font-size: 16px;
			/* IE9以下不支持rgba模式 */
			background-color: rgba(0, 0, 0, 0.5);
			/* 兼容IE8及以下 */
			filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#7f000000, endColorstr=#7f000000);
			display: none;
			justify-content: center;
			align-items: center;
		}

		/* 弹出框主体 */
		.popup {
			background-color: #ffffff;
			width: max-content;
			text-align: center;
		}

		/* 弹出框的按钮 */
		.popup button {
			color: #000000;
			font-family: "Segoe UI", Arial, Helvetica, sans-serif;
			font-size: 20px;
			width: 320px;
			height: 50px;
			border: solid 1px #cccccc;
			margin: 0px auto;
			background-color: #ffffff;
		}
	</style>
	<div style="padding:0 16px;text-align:center" class="main">
		<h1>图片混淆</h1>
		<div id="picinfo" style="font-size:0.8rem;color:#666;display:block;">&emsp;</div>
		<div id="imgwrap" class="square" onclick="showPopup()">
			<img id="kimg" src="" />
		</div>
		<div id="sign" class="square" onclick="xuanze()">
			<div><span style="font-size:100px;line-height:60px;">+</span><br /><span>点击选择图片</span></div>
		</div>
		<div id="loading" class="square">
			正在生成中...
		</div>
		<div id="ATBtnDiv1" style="margin-top:0.5em;display:none;justify-content:center;align-items:center;">
			<input style="display:block;border:2px;" onchange="ipt()" type="file" id="ipt" accept="image/*"></input>
			<a id="baocun" style="text-decoration:underline;display:block;color:#0000FF;" onclick="saveLinkOnClick()">保存图片</a>
		</div>
		<div id="ATBtnDiv2" style="margin-top:0.5em;display:none;justify-content:center;align-items:center;">
			<button style="margin:4px;" onclick="baocun2()">保存图片(备用2)</button>
			<button style="margin:4px;" onclick="baocun3()">保存图片(备用3)</button>
			<button style="margin:4px;" onclick="baocun4()">保存图片(备用4)</button>
		</div>
		<div id="overlay" onclick="hidePopup()">
			<div class="popup">
				<div><button onclick="xuanze()">选择图片</button></div>
				<div><button onclick="baocun()">保存图片</button></div>
			</div>
		</div>
		<div style="height:1.8em;margin-top:0.5em;">
			<span class="shuoming">加密模式：</span>
			<select id="slct" onchange="selectonchange()">
				<option value="pe1">兼容PicEncrypt:行模式</option>
				<option value="pe2">兼容PicEncrypt:行+列模式</option>
				<option value="b">方块混淆</option>
				<option value="c2">行像素混淆</option>
				<option value="c">像素混淆</option>
			</select>
		</div>
		<div style="height:2.5em;margin-top:0.2em;">
			<span class="shuoming">请输入密钥:</span>
			<input style="display:none" type="text" id="ikey" placeholder="(任意字符串)"></input>
			<input type="number" id="ikey2" value="0.123" placeholder="(0到1之间小数)"></input>
		</div>
		<div style="height:2.5em;margin-top:0.2em;">
			<button onclick="jiami()">&ensp;加密&ensp;</button>
			&emsp;
			<button onclick="jiemi()">解密</button>
			&emsp;
			<button onclick="huanyuan()">&ensp;还原&ensp;</button>
		</div>
		<div style="font-size:20px;padding:1rem 0 0 0;">
			<span>
				<b>免责声明: 页面仅供技术研究使用，<br />&#35831;&#21247;&#29992;&#20110;&#38750;&#27861;&#29992;&#36884;&#65292;<br />否则后果作者概不负责！</b>
			</span>
		</div>
		<div style="color:#666;padding:1rem 0 0 0;font-size:15px;">
			<span>1. 加密/解密完成后, 点击图片即可进行保存等操作;</span><br />
			<span>2. 如果"点击选择图片"的框点击没有反应, 请尝试<a onclick="showATBtn()" style="text-decoration:underline;">点击这里</a>;</span><br />
			<br />
			<span>图片混淆 v0.2.2</span><br />
			<span>原作者: ybzjdsd</span><br />
			<span>由"风云de寒冰"修改并补档</span>
		</div>

	</div>
	<script>
		var md5 = (function () {
			function MD5(string) {
				var x = Array();
				var k, AA, BB, CC, DD, a, b, c, d;
				var S11 = 7, S12 = 12, S13 = 17, S14 = 22;
				var S21 = 5, S22 = 9, S23 = 14, S24 = 20;
				var S31 = 4, S32 = 11, S33 = 16, S34 = 23;
				var S41 = 6, S42 = 10, S43 = 15, S44 = 21;
				string = Utf8Encode(string);
				x = ConvertToWordArray(string);
				a = 0x67452301;
				b = 0xEFCDAB89;
				c = 0x98BADCFE;
				d = 0x10325476;
				for (k = 0; k < x.length; k += 16) {
					AA = a;
					BB = b;
					CC = c;
					DD = d;
					a = FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
					d = FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
					c = FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
					b = FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
					a = FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
					d = FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
					c = FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
					b = FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
					a = FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
					d = FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
					c = FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
					b = FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
					a = FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
					d = FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
					c = FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
					b = FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
					a = GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
					d = GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
					c = GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
					b = GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
					a = GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
					d = GG(d, a, b, c, x[k + 10], S22, 0x2441453);
					c = GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
					b = GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
					a = GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
					d = GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
					c = GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
					b = GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
					a = GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
					d = GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
					c = GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
					b = GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
					a = HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
					d = HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
					c = HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
					b = HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
					a = HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
					d = HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
					c = HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
					b = HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
					a = HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
					d = HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
					c = HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
					b = HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
					a = HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
					d = HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
					c = HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
					b = HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
					a = II(a, b, c, d, x[k + 0], S41, 0xF4292244);
					d = II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
					c = II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
					b = II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
					a = II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
					d = II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
					c = II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
					b = II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
					a = II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
					d = II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
					c = II(c, d, a, b, x[k + 6], S43, 0xA3014314);
					b = II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
					a = II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
					d = II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
					c = II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
					b = II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
					a = AddUnsigned(a, AA);
					b = AddUnsigned(b, BB);
					c = AddUnsigned(c, CC);
					d = AddUnsigned(d, DD);
				}
				var temp = WordToHex(a) + WordToHex(b) + WordToHex(c) + WordToHex(d);
				return temp.toUpperCase();
			}
			function RotateLeft(lValue, iShiftBits) {
				return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
			}
			function AddUnsigned(lX, lY) {
				var lX4, lY4, lX8, lY8, lResult;
				lX8 = (lX & 0x80000000);
				lY8 = (lY & 0x80000000);
				lX4 = (lX & 0x40000000);
				lY4 = (lY & 0x40000000);
				lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
				if (lX4 & lY4) {
					return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
				}
				if (lX4 | lY4) {
					if (lResult & 0x40000000) {
						return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
					} else {
						return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
					}
				} else {
					return (lResult ^ lX8 ^ lY8);
				}
			}
			function F(x, y, z) {
				return (x & y) | ((~x) & z);
			}
			function G(x, y, z) {
				return (x & z) | (y & (~z));
			}
			function H(x, y, z) {
				return (x ^ y ^ z);
			}
			function I(x, y, z) {
				return (y ^ (x | (~z)));
			}
			function FF(a, b, c, d, x, s, ac) {
				a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
				return AddUnsigned(RotateLeft(a, s), b);
			}
			function GG(a, b, c, d, x, s, ac) {
				a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
				return AddUnsigned(RotateLeft(a, s), b);
			}
			function HH(a, b, c, d, x, s, ac) {
				a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
				return AddUnsigned(RotateLeft(a, s), b);
			}
			function II(a, b, c, d, x, s, ac) {
				a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
				return AddUnsigned(RotateLeft(a, s), b);
			}
			function ConvertToWordArray(string) {
				var lWordCount;
				var lMessageLength = string.length;
				var lNumberOfWords_temp1 = lMessageLength + 8;
				var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
				var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
				var lWordArray = Array(lNumberOfWords - 1);
				var lBytePosition = 0;
				var lByteCount = 0;
				while (lByteCount < lMessageLength) {
					lWordCount = (lByteCount - (lByteCount % 4)) / 4;
					lBytePosition = (lByteCount % 4) * 8;
					lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition));
					lByteCount++;
				}
				lWordCount = (lByteCount - (lByteCount % 4)) / 4;
				lBytePosition = (lByteCount % 4) * 8;
				lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
				lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
				lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
				return lWordArray;
			}
			function WordToHex(lValue) {
				var WordToHexValue = "", WordToHexValue_temp = "", lByte, lCount;
				for (lCount = 0; lCount <= 3; lCount++) {
					lByte = (lValue >>> (lCount * 8)) & 255;
					WordToHexValue_temp = "0" + lByte.toString(16);
					WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length - 2, 2);
				}
				return WordToHexValue;
			}
			function Utf8Encode(string) {
				var utftext = "";
				for (var n = 0; n < string.length; n++) {
					var c = string.charCodeAt(n);
					if (c < 128) {
						utftext += String.fromCharCode(c);
					} else if ((c > 127) && (c < 2048)) {
						utftext += String.fromCharCode((c >> 6) | 192);
						utftext += String.fromCharCode((c & 63) | 128);
					} else {
						utftext += String.fromCharCode((c >> 12) | 224);
						utftext += String.fromCharCode(((c >> 6) & 63) | 128);
						utftext += String.fromCharCode((c & 63) | 128);
					}
				}
				return utftext;
			}
			return MD5
		}())
	</script>
	<script>
		let IMG = new Image();
		let SIZE = 4294967296;
		let SignShow = true;
		let Pic_SRC = "";
		let Pic_DataUrl = "";
		let OriginalPic_SRC = "";
		let OriginalPic_DataUrl = "";
		let INFO1 = "请先上传图片！";

		function showPopup() {
			document.getElementById("overlay").style.display = "flex"
		}
		function hidePopup() {
			document.getElementById("overlay").style.display = "none"
		}
		function selectonchange() {
			if (["pe1", "pe2"].indexOf(document.getElementById("slct").value) == -1) {
				document.getElementById("ikey2").style.display = "none";
				document.getElementById("ikey").style.display = "inline";
			} else {
				document.getElementById("ikey").style.display = "none";
				document.getElementById("ikey2").style.display = "inline";
			}
		}

		function showATBtn(){
			document.getElementById("ATBtnDiv1").style.display = "flex";
			document.getElementById("ATBtnDiv2").style.display = "flex";
		}

		function xuanze() {
			hidePopup();
			document.getElementById("ipt").click();
		}

		function huanyuan() {
			if (Pic_SRC == "") { alert(INFO1) } else {
				setpic(OriginalPic_DataUrl);
				document.getElementById("picinfo").innerHTML = "&emsp;";
			}
		}

		function baocun() {
			hidePopup();
			if (Pic_SRC == "") {
				alert(INFO1);
			}
			else {
				// 使用dataURL
				let alink = document.createElement("a");
				alink.style = 'display:none;';
				alink.download = "PicEncrypt" + String(Date.now()) + ".png";
				alink.href = Pic_DataUrl;
				alink.dataset.downloadurl = ["image/png", alink.download, alink.href].join(':');
				document.body.appendChild(alink);
				alink.click();
				document.body.removeChild(alink);
			}
		}
		function baocun2() {
			if (Pic_SRC == "") {
				alert(INFO1);
			}
			else {
				// 使用objectURL
				let alink = document.createElement("a");
				alink.style = 'display:none;';
				alink.download = "PicEncrypt" + String(Date.now()) + ".png";
				alink.href = Pic_SRC;
				alink.dataset.downloadurl = ["image/png", alink.download, alink.href].join(':');
				document.body.appendChild(alink);
				alink.click();
				document.body.removeChild(alink);
			}
		}
		function baocun3() {
			if (Pic_SRC == "") {
				alert(INFO1);
			}
			else {
				window.location.href = Pic_DataUrl.replace("image/png", "image/octet-stream");
			}
		}
        function baocun4() {
			if (Pic_SRC == "") {
				alert(INFO1);
			}
			else {
            	window.open('about:blank', 'image').document.write("<img src='" + Pic_DataUrl + "' alt='【图片】'/>");
			}
        }

		function saveLinkOnClick() {
			document.getElementById('baocun').download = 'PicEncrypt' + String(Date.now()) + '.png';
			document.getElementById('baocun').href = Pic_SRC;
		}

		function setpic(DataUrl) {
			if (Pic_SRC) {
				URL.revokeObjectURL(Pic_SRC)
			}
			Pic_DataUrl = DataUrl;
			Pic_SRC = URL.createObjectURL(dataURLtoBlob(DataUrl));
			IMG.src = Pic_SRC;
			document.getElementById("kimg").src = Pic_SRC;
		}

		function dataURLtoBlob(dataurl) {
			var arr = dataurl.split(',');
			//注意base64的最后面中括号和引号是不转译的   
			var _arr = arr[1].substring(0, arr[1].length - 2);
			var mime = arr[0].match(/:(.*?);/)[1],
				bstr = atob(_arr),
				n = bstr.length,
				u8arr = new Uint8Array(n);
			while (n--) {
				u8arr[n] = bstr.charCodeAt(n);
			}
			return new Blob([u8arr], {
				type: mime
			});
		}

		function ipt() {
			let oFReader = new FileReader();
			oFReader.onload = function (event) {
				let newimg_dataurl = event.target.result;
				setpic(newimg_dataurl);
				OriginalPic_DataUrl = Pic_DataUrl;
				OriginalPic_SRC = Pic_SRC;
				IMG.onload = function(){
					if(IMG.width > IMG.height){
						document.getElementById("kimg").style.height = "200px";
						document.getElementById("kimg").style.width = "auto";
					}else{
						document.getElementById("kimg").style.height = "auto";
						document.getElementById("kimg").style.width = "200px";
					}
				}
				if (Pic_SRC != "") {
					if (SignShow) {
						document.getElementById("sign").style.display = "none";
						document.getElementById("imgwrap").style.display = "flex";
						document.getElementById("kimg").style.display = "block";
						SignShow = false
					}
					document.getElementById("picinfo").innerHTML = "&emsp;";
				}
			}
			let ofile = document.getElementById("ipt").files[0];
			oFReader.readAsDataURL(ofile);
		}

		function jiami() {
			if (Pic_SRC == "") { alert(INFO1) } else {
				let t = Date.now();
				let s = "";
				let a = document.getElementById("slct").value;
				let k = document.getElementById("ikey").value;
				let k2 = parseFloat(document.getElementById("ikey2").value);
				document.getElementById("imgwrap").style.display = "none";
				document.getElementById("loading").style.display = "block";
				requestAnimationFrame(function () {
					requestAnimationFrame(function () {
						if (a == "b") {
							s = encryptB2(IMG, k, 32, 32);
						} else if (a == "c") {
							s = encryptC(IMG, k);
						} else if (a == "pe1") {
							s = encryptPE1(IMG, k2);
						} else if (a == "pe2") {
							s = encryptPE2(IMG, k2);
						} else {
							s = encryptC2(IMG, k);
						}
						setpic(s[0]);
						document.getElementById("picinfo").innerHTML = "size:&ensp;" + s[1] + "×" + s[2] + "&emsp;time:&ensp;" + (Date.now() - t).toString() + "ms"
						document.getElementById("picinfo").style.display = "block";
						document.getElementById("imgwrap").style.display = "flex";
						document.getElementById("loading").style.display = "none";
					})
				})
			}
		}
		function jiemi() {
			if (Pic_SRC == "") { alert(INFO1) } else {
				let t = Date.now();
				let s = "";
				let a = document.getElementById("slct").value;
				let k = document.getElementById("ikey").value;
				let k2 = parseFloat(document.getElementById("ikey2").value);
				document.getElementById("imgwrap").style.display = "none";
				document.getElementById("loading").style.display = "block";
				requestAnimationFrame(function () {
					requestAnimationFrame(function () {
						if (a == "b") {
							s = decryptB2(IMG, k, 32, 32);
						} else if (a == "c") {
							s = decryptC(IMG, k);
						} else if (a == "pe1") {
							s = decryptPE1(IMG, k2);
						} else if (a == "pe2") {
							s = decryptPE2(IMG, k2);
						} else {
							s = decryptC2(IMG, k);
						}
						setpic(s[0]);
						document.getElementById("kimg").src = Pic_SRC;
						document.getElementById("kimg").style.display = "block";
						document.getElementById("picinfo").innerHTML = "size:&ensp;" + s[1] + "×" + s[2] + "&emsp;time:&ensp;" + (Date.now() - t).toString() + "ms"
						document.getElementById("picinfo").style.display = "block";
						document.getElementById("imgwrap").style.display = "flex";
						document.getElementById("loading").style.display = "none";
					})
				})
			}
		}

		//随机打乱
		function amess(arrlength, ast) {
			var rand, temp;
			var arr = new Array(arrlength).fill(0).map((a, b) => b);
			for (let i = arrlength - 1; i > 0; i -= 1) {
				rand = parseInt(md5(ast + i.toString()).substr(0, 7), 16) % (i + 1);
				temp = arr[rand];
				arr[rand] = arr[i]
				arr[i] = temp;
			}
			return arr;
		}

		//块混淆
		function encryptB2(img1, key, sx, sy) {
			var cv = document.createElement("canvas");
			var cvd = cv.getContext("2d");
			var wid = img1.width;
			var hit = img1.height;
			var wid1 = wid;
			var hit1 = hit;
			var imgdata;
			var oimgdata;
			var xl = new Array();
			var yl = new Array();
			var k = 8;
			var m = 0;
			var n = 0;
			var ssx;
			var ssy;
			//缩放大小
			if (wid * hit > SIZE) {
				wid = parseInt(Math.pow(SIZE * img1.width / img1.height, 1 / 2));
				hit = parseInt(Math.pow(SIZE * img1.height / img1.width, 1 / 2));
			}
			wid1 = wid;
			hit1 = hit;
			while (wid % sx > 0) {
				wid++
			}
			while (hit % sy > 0) {
				hit++
			}
			ssx = wid / sx;
			ssy = hit / sy;
			cv.width = wid;
			cv.height = hit;
			cvd.drawImage(img1, 0, 0, wid1, hit1);
			cvd.drawImage(img1, 0, hit1, wid1, hit1);
			cvd.drawImage(img1, wid1, 0, wid1, hit1);
			cvd.drawImage(img1, wid1, hit1, wid1, hit1);
			imgdata = cvd.getImageData(0, 0, wid, hit);
			oimgdata = cvd.createImageData(wid, hit);
			xl = amess(sx, key);
			yl = amess(sy, key);
			for (let i = 0; i < wid; i++) {
				for (let j = 0; j < hit; j++) {
					m = i;
					n = j;
					m = (xl[((n / ssy) | 0) % sx] * ssx + m) % wid;
					m = xl[(m / ssx) | 0] * ssx + m % ssx;
					n = (yl[((m / ssx) | 0) % sy] * ssy + n) % hit;
					n = yl[(n / ssy) | 0] * ssy + n % ssy;
					oimgdata.data[4 * (i + j * wid)] = imgdata.data[4 * (m + n * wid)];
					oimgdata.data[4 * (i + j * wid) + 1] = imgdata.data[4 * (m + n * wid) + 1];
					oimgdata.data[4 * (i + j * wid) + 2] = imgdata.data[4 * (m + n * wid) + 2];
					oimgdata.data[4 * (i + j * wid) + 3] = imgdata.data[4 * (m + n * wid) + 3];
				}
			}
			cvd.putImageData(oimgdata, 0, 0);
			return [cv.toDataURL(), wid, hit]
		}

		function decryptB2(img1, key, sx, sy) {
			var cv = document.createElement("canvas");
			var cvd = cv.getContext("2d");
			var wid = img1.width;
			var hit = img1.height;
			var wid1 = wid;
			var hit1 = hit;
			var imgdata;
			var oimgdata;
			var xl = new Array();
			var yl = new Array();
			var k = 8;
			var m = 0;
			var n = 0;
			var ssx;
			var ssy;
			wid1 = wid;
			hit1 = hit;
			while (wid % sx > 0) {
				wid++
			}
			while (hit % sy > 0) {
				hit++
			}
			ssx = wid / sx;
			ssy = hit / sy;
			cv.width = wid;
			cv.height = hit;
			cvd.drawImage(img1, 0, 0, wid1, hit1);
			cvd.drawImage(img1, 0, hit1, wid1, hit1);
			cvd.drawImage(img1, wid1, 0, wid1, hit1);
			cvd.drawImage(img1, wid1, hit1, wid1, hit1);
			imgdata = cvd.getImageData(0, 0, wid, hit);
			oimgdata = cvd.createImageData(wid, hit);
			xl = amess(sx, key);
			yl = amess(sy, key);
			for (let i = 0; i < wid; i++) {
				for (let j = 0; j < hit; j++) {
					m = i;
					n = j;
					m = (xl[((n / ssy) | 0) % sx] * ssx + m) % wid;
					m = xl[(m / ssx) | 0] * ssx + m % ssx;
					n = (yl[((m / ssx) | 0) % sy] * ssy + n) % hit;
					n = yl[(n / ssy) | 0] * ssy + n % ssy;
					oimgdata.data[4 * (m + n * wid)] = imgdata.data[4 * (i + j * wid)];
					oimgdata.data[4 * (m + n * wid) + 1] = imgdata.data[4 * (i + j * wid) + 1];
					oimgdata.data[4 * (m + n * wid) + 2] = imgdata.data[4 * (i + j * wid) + 2];
					oimgdata.data[4 * (m + n * wid) + 3] = imgdata.data[4 * (i + j * wid) + 3];
				}
			}
			cvd.putImageData(oimgdata, 0, 0);
			return [cv.toDataURL(), wid, hit]
		}

		//算法C,逐像素混淆
		function encryptC(img1, key) {
			var cv = document.createElement("canvas");
			var cvd = cv.getContext("2d");
			var wid = img1.width;
			var hit = img1.height;
			var imgdata;
			var oimgdata;
			var xl = new Array();
			var yl = new Array();
			var m = 0;
			var n = 0;
			//缩放大小
			if (wid * hit > SIZE) {
				wid = parseInt(Math.pow(SIZE * img1.width / img1.height, 1 / 2));
				hit = parseInt(Math.pow(SIZE * img1.height / img1.width, 1 / 2));
			}
			cv.width = wid;
			cv.height = hit;
			cvd.drawImage(img1, 0, 0, wid, hit);
			imgdata = cvd.getImageData(0, 0, wid, hit);
			oimgdata = cvd.createImageData(wid, hit);
			xl = amess(wid, key);
			yl = amess(hit, key);
			for (let i = 0; i < wid; i++) {
				for (let j = 0; j < hit; j++) {
					m = i;
					n = j;
					m = (xl[n % wid] + m) % wid;
					m = xl[m];
					n = (yl[m % hit] + n) % hit;
					n = yl[n];
					oimgdata.data[4 * (i + j * wid)] = imgdata.data[4 * (m + n * wid)];
					oimgdata.data[4 * (i + j * wid) + 1] = imgdata.data[4 * (m + n * wid) + 1];
					oimgdata.data[4 * (i + j * wid) + 2] = imgdata.data[4 * (m + n * wid) + 2];
					oimgdata.data[4 * (i + j * wid) + 3] = imgdata.data[4 * (m + n * wid) + 3];
				}
			}
			cvd.putImageData(oimgdata, 0, 0);
			return [cv.toDataURL(), wid, hit]
		}

		function decryptC(img1, key) {
			var cv = document.createElement("canvas");
			var cvd = cv.getContext("2d");
			var wid = img1.width;
			var hit = img1.height;
			var imgdata;
			var oimgdata;
			var xl = new Array();
			var yl = new Array();
			var m = 0;
			var n = 0;
			cv.width = wid;
			cv.height = hit;
			cvd.drawImage(img1, 0, 0, wid, hit);
			imgdata = cvd.getImageData(0, 0, wid, hit);
			oimgdata = cvd.createImageData(wid, hit);
			xl = amess(wid, key);
			yl = amess(hit, key);
			for (let i = 0; i < wid; i++) {
				for (let j = 0; j < hit; j++) {
					m = i;
					n = j;
					m = (xl[n % wid] + m) % wid;
					m = xl[m];
					n = (yl[m % hit] + n) % hit;
					n = yl[n];
					oimgdata.data[4 * (m + n * wid)] = imgdata.data[4 * (i + j * wid)];
					oimgdata.data[4 * (m + n * wid) + 1] = imgdata.data[4 * (i + j * wid) + 1];
					oimgdata.data[4 * (m + n * wid) + 2] = imgdata.data[4 * (i + j * wid) + 2];
					oimgdata.data[4 * (m + n * wid) + 3] = imgdata.data[4 * (i + j * wid) + 3];
				}
			}
			cvd.putImageData(oimgdata, 0, 0);
			return [cv.toDataURL(), wid, hit]
		}

		//行像素混淆
		function encryptC2(img1, key) {
			var cv = document.createElement("canvas");
			var cvd = cv.getContext("2d");
			var wid = img1.width;
			var hit = img1.height;
			var imgdata;
			var oimgdata;
			var xl = new Array();
			var yl = new Array();
			var m = 0;
			var n = 0;
			//缩放大小
			if (wid * hit > SIZE) {
				wid = parseInt(Math.pow(SIZE * img1.width / img1.height, 1 / 2));
				hit = parseInt(Math.pow(SIZE * img1.height / img1.width, 1 / 2));
			}
			cv.width = wid;
			cv.height = hit;
			cvd.drawImage(img1, 0, 0, wid, hit);
			imgdata = cvd.getImageData(0, 0, wid, hit);
			oimgdata = cvd.createImageData(wid, hit);
			xl = amess(wid, key);
			yl = amess(hit, key);
			for (let i = 0; i < wid; i++) {
				for (let j = 0; j < hit; j++) {
					m = i;
					n = j;
					m = (xl[n % wid] + m) % wid;
					m = xl[m];
					oimgdata.data[4 * (i + j * wid)] = imgdata.data[4 * (m + n * wid)];
					oimgdata.data[4 * (i + j * wid) + 1] = imgdata.data[4 * (m + n * wid) + 1];
					oimgdata.data[4 * (i + j * wid) + 2] = imgdata.data[4 * (m + n * wid) + 2];
					oimgdata.data[4 * (i + j * wid) + 3] = imgdata.data[4 * (m + n * wid) + 3];
				}
			}
			cvd.putImageData(oimgdata, 0, 0);
			return [cv.toDataURL(), wid, hit]
		}

		function decryptC2(img1, key) {
			var cv = document.createElement("canvas");
			var cvd = cv.getContext("2d");
			var wid = img1.width;
			var hit = img1.height;
			var imgdata;
			var oimgdata;
			var xl = new Array();
			var yl = new Array();
			var m = 0;
			var n = 0;
			cv.width = wid;
			cv.height = hit;
			cvd.drawImage(img1, 0, 0, wid, hit);
			imgdata = cvd.getImageData(0, 0, wid, hit);
			oimgdata = cvd.createImageData(wid, hit);
			xl = amess(wid, key);
			yl = amess(hit, key);
			for (let i = 0; i < wid; i++) {
				for (let j = 0; j < hit; j++) {
					m = i;
					n = j;
					m = (xl[n % wid] + m) % wid;
					m = xl[m];
					oimgdata.data[4 * (m + n * wid)] = imgdata.data[4 * (i + j * wid)];
					oimgdata.data[4 * (m + n * wid) + 1] = imgdata.data[4 * (i + j * wid) + 1];
					oimgdata.data[4 * (m + n * wid) + 2] = imgdata.data[4 * (i + j * wid) + 2];
					oimgdata.data[4 * (m + n * wid) + 3] = imgdata.data[4 * (i + j * wid) + 3];
				}
			}
			cvd.putImageData(oimgdata, 0, 0);
			return [cv.toDataURL(), wid, hit]
		}

		//picencrypt算法
		function produceLogisticSort(a, b) {
			return a[0] - b[0]
		}
		function produceLogistic(x1, n) {
			let l = new Array(n);
			let x = x1;
			l[0] = [x, 0];
			for (let i = 1; i < n; i++) {
				x = 3.9999999 * x * (1 - x);
				l[i] = [x, i]
			}
			return l
		}

		//行混淆
		function encryptPE1(img1, key) {
			var cv = document.createElement("canvas");
			var cvd = cv.getContext("2d");
			var wid = img1.width;
			var hit = img1.height;
			var imgdata;
			var oimgdata;
			var arrayaddress = new Array();
			var m = 0;
			var n = 0;

			//缩放大小
			if (wid * hit > SIZE) {
				wid = parseInt(Math.pow(SIZE * img1.width / img1.height, 1 / 2));
				hit = parseInt(Math.pow(SIZE * img1.height / img1.width, 1 / 2));
			}
			cv.width = wid;
			cv.height = hit;
			cvd.drawImage(img1, 0, 0, wid, hit);
			imgdata = cvd.getImageData(0, 0, wid, hit);
			oimgdata = cvd.createImageData(wid, hit);
			arrayaddress = produceLogistic(key, wid).sort(produceLogisticSort).map(x => x[1]);
			for (let i = 0; i < wid; i++) {
				for (let j = 0; j < hit; j++) {
					m = arrayaddress[i];
					oimgdata.data[4 * (i + j * wid)] = imgdata.data[4 * (m + j * wid)];
					oimgdata.data[4 * (i + j * wid) + 1] = imgdata.data[4 * (m + j * wid) + 1];
					oimgdata.data[4 * (i + j * wid) + 2] = imgdata.data[4 * (m + j * wid) + 2];
					oimgdata.data[4 * (i + j * wid) + 3] = imgdata.data[4 * (m + j * wid) + 3];
				}
			}
			cvd.putImageData(oimgdata, 0, 0);
			return [cv.toDataURL(), wid, hit]
		}

		function decryptPE1(img1, key) {
			var cv = document.createElement("canvas");
			var cvd = cv.getContext("2d");
			var wid = img1.width;
			var hit = img1.height;
			var imgdata;
			var oimgdata;
			var arrayaddress = new Array();
			var m = 0;
			var n = 0;
			cv.width = wid;
			cv.height = hit;
			cvd.drawImage(img1, 0, 0, wid, hit);
			imgdata = cvd.getImageData(0, 0, wid, hit);
			oimgdata = cvd.createImageData(wid, hit);
			arrayaddress = produceLogistic(key, wid).sort(produceLogisticSort).map(x => x[1]);
			for (let i = 0; i < wid; i++) {
				for (let j = 0; j < hit; j++) {
					m = arrayaddress[i];
					oimgdata.data[4 * (m + j * wid)] = imgdata.data[4 * (i + j * wid)];
					oimgdata.data[4 * (m + j * wid) + 1] = imgdata.data[4 * (i + j * wid) + 1];
					oimgdata.data[4 * (m + j * wid) + 2] = imgdata.data[4 * (i + j * wid) + 2];
					oimgdata.data[4 * (m + j * wid) + 3] = imgdata.data[4 * (i + j * wid) + 3];
				}
			}
			cvd.putImageData(oimgdata, 0, 0);
			return [cv.toDataURL(), wid, hit]
		}

		//行+列混淆
		function encryptPE2(img1, key) {
			var cv = document.createElement("canvas");
			var cvd = cv.getContext("2d");
			var wid = img1.width;
			var hit = img1.height;
			var imgdata;
			var oimgdata;
			var o2imgdata;
			var arrayaddress = new Array();
			var x = key;
			var m = 0;
			var n = 0;
			if (wid * hit > SIZE) {
				wid = parseInt(Math.pow(SIZE * img1.width / img1.height, 1 / 2));
				hit = parseInt(Math.pow(SIZE * img1.height / img1.width, 1 / 2));
			}
			cv.width = wid;
			cv.height = hit;
			cvd.drawImage(img1, 0, 0, wid, hit);
			imgdata = cvd.getImageData(0, 0, wid, hit);
			oimgdata = cvd.createImageData(wid, hit);
			o2imgdata = cvd.createImageData(wid, hit);
			for (let j = 0; j < hit; j++) {
				arrayaddress = produceLogistic(x, wid);
				x = arrayaddress[wid - 1][0];
				arrayaddress = arrayaddress.sort(produceLogisticSort).map(a => a[1])
				for (let i = 0; i < wid; i++) {
					m = arrayaddress[i];
					oimgdata.data[4 * (i + j * wid)] = imgdata.data[4 * (m + j * wid)];
					oimgdata.data[4 * (i + j * wid) + 1] = imgdata.data[4 * (m + j * wid) + 1];
					oimgdata.data[4 * (i + j * wid) + 2] = imgdata.data[4 * (m + j * wid) + 2];
					oimgdata.data[4 * (i + j * wid) + 3] = imgdata.data[4 * (m + j * wid) + 3];
				}
			}
			x = key;
			for (let i = 0; i < wid; i++) {
				arrayaddress = produceLogistic(x, hit);
				x = arrayaddress[hit - 1][0];
				arrayaddress = arrayaddress.sort(produceLogisticSort).map(a => a[1])
				for (let j = 0; j < hit; j++) {
					n = arrayaddress[j];
					o2imgdata.data[4 * (i + j * wid)] = oimgdata.data[4 * (i + n * wid)];
					o2imgdata.data[4 * (i + j * wid) + 1] = oimgdata.data[4 * (i + n * wid) + 1];
					o2imgdata.data[4 * (i + j * wid) + 2] = oimgdata.data[4 * (i + n * wid) + 2];
					o2imgdata.data[4 * (i + j * wid) + 3] = oimgdata.data[4 * (i + n * wid) + 3];
				}
			}
			cvd.putImageData(o2imgdata, 0, 0);
			return [cv.toDataURL(), wid, hit]
		}

		function decryptPE2(img1, key) {
			var cv = document.createElement("canvas");
			var cvd = cv.getContext("2d");
			var wid = img1.width;
			var hit = img1.height;
			var imgdata;
			var oimgdata;
			var o2imgdata;
			var arrayaddress = new Array();
			var x = key;
			var m = 0;
			var n = 0;
			cv.width = wid;
			cv.height = hit;
			cvd.drawImage(img1, 0, 0, wid, hit);
			imgdata = cvd.getImageData(0, 0, wid, hit);
			oimgdata = cvd.createImageData(wid, hit);
			o2imgdata = cvd.createImageData(wid, hit);
			for (let i = 0; i < wid; i++) {
				arrayaddress = produceLogistic(x, hit);
				x = arrayaddress[hit - 1][0];
				arrayaddress = arrayaddress.sort(produceLogisticSort).map(a => a[1])
				for (let j = 0; j < hit; j++) {
					n = arrayaddress[j];
					oimgdata.data[4 * (i + n * wid)] = imgdata.data[4 * (i + j * wid)];
					oimgdata.data[4 * (i + n * wid) + 1] = imgdata.data[4 * (i + j * wid) + 1];
					oimgdata.data[4 * (i + n * wid) + 2] = imgdata.data[4 * (i + j * wid) + 2];
					oimgdata.data[4 * (i + n * wid) + 3] = imgdata.data[4 * (i + j * wid) + 3];
				}
			}
			x = key;
			for (let j = 0; j < hit; j++) {
				arrayaddress = produceLogistic(x, wid);
				x = arrayaddress[wid - 1][0];
				arrayaddress = arrayaddress.sort(produceLogisticSort).map(a => a[1])
				for (let i = 0; i < wid; i++) {
					m = arrayaddress[i];
					o2imgdata.data[4 * (m + j * wid)] = oimgdata.data[4 * (i + j * wid)];
					o2imgdata.data[4 * (m + j * wid) + 1] = oimgdata.data[4 * (i + j * wid) + 1];
					o2imgdata.data[4 * (m + j * wid) + 2] = oimgdata.data[4 * (i + j * wid) + 2];
					o2imgdata.data[4 * (m + j * wid) + 3] = oimgdata.data[4 * (i + j * wid) + 3];
				}
			}
			cvd.putImageData(o2imgdata, 0, 0);
			return [cv.toDataURL(), wid, hit]
		}
	</script>
</body>

</html>